#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) angelipin (angelipin@126.com). All right reservered.

import os
import time
import stat
import sys
from ftplib import FTP
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from windowUi import Ui_FtpView
import quickConnectDlg


__version__ = "1.0.0"


class LocalFileInfo:
	__name = None
	__stat = None
	__type = None
	__path = None

	
	def __init__(self,filepath):
		self.__name = os.path.basename(filepath)
		self.__stat = os.stat(filepath)
		self.__path = filepath
		self.__flag = 1

		if os.path.isdir(filepath):
			self.__type = "Dir"
		else:
			self.__type = "File"
		return
	
	def __getattr__(self,name):
		if name == 'name':
			return self.__name
		elif name == 'size':
			return self.__stat[stat.ST_SIZE]
		elif name == 'mtime':
			return self.__stat[stat.ST_MTIME]
		elif name == 'stat':
			return self.__stat
		elif name == 'type':
			return self.__type
		elif name == 'path':
			return self.__path
		elif name == 'flag':
			return self.__flag
		else:
			raise AttributeError,name
	
	def is_dir(self):
		return stat.S_ISDIR(self.__stat[stat.ST_MODE])
	
	def is_regular(self):
		return stat.S_ISREG(self.__stat[stat.ST_MODE])
	
	def is_link(self):
		return stat.S_ISLINK(self.__stat[stat.ST_MODE])

	def setflag(self,int):
		self.__flag = int
		return


class FreeFtpView(QMainWindow):
	def __init__(self):
		QMainWindow.__init__(self)
		self.ui = Ui_FtpView()

		self.ui.setupUi(self)

		ftpMenu = self.ui.menubar.addMenu("&Ftp")
		quickconnectAction = self.createAction("&Connect",self.quickConnect,"Ctrl+C","connect","quick connect to server")
		quitAction = self.createAction("&Quit",self.close,"Ctrl+Q","quit","close the application")
		self.addActions(ftpMenu,(quickconnectAction,quitAction))

		
		disconnectAction = self.createAction("&DisConnect",self.disconnect,"Ctrl+D","disconnect","Disconnect from Server")
		transferAction = self.createAction("&Transfer",self.transfer,"Ctrl+T","transfer","Transfer File")
		addLocalFileToQueueAction = self.createAction("Add &Local",self.addLocalFileToQueue,"Ctrl+L","selectupload","Add Local File to Queue")
		addRemoteFileToQueueAction = self.createAction("Add &Remote",self.addRemoteFileToQueue,"Ctrl+R","selectdownload","Add Remote File to Queue")
		




		self.addActions(self.ui.toolBar,(quickconnectAction,disconnectAction,transferAction,addLocalFileToQueueAction,addRemoteFileToQueueAction))

		self.isFtpConnected = 0
		self.ftp = FTP()
		self.ftp.set_debuglevel(2)

		#treat fileList
		self.fileList = []
		self.remotefilelist = []
		self.homeDir = os.getenv('HOME')
		self.currentDir = self.homeDir
		self.remoteCurrentDir = '.'
		filelist = os.listdir(self.homeDir)
		for f in filelist:
			fileinfo = LocalFileInfo(os.path.join(self.homeDir,f))
			self.fileList.append(fileinfo)
		#end treat fileList
		
		#  Add item to TreeWidget
		item = QTreeWidgetItem([u'上层目录',' ',' ',' '])
		item.setIcon(0,QIcon(":/ICON/parent_dir.png"))
		self.ui.localWidget.addTopLevelItem(item)
		for f in self.fileList:
			filename = self.encode(f.name,'UTF-8')
			item = QTreeWidgetItem([filename,str(f.size),time.ctime(f.mtime),' '])
			if f.type == 'Dir':
				item.setIcon(0,QIcon(":/ICON/folder.png"))
			self.ui.localWidget.addTopLevelItem(item)
		# End Add item to TreeWidget
		self.connect(self.ui.localWidget,SIGNAL('itemDoubleClicked(QTreeWidgetItem *,int)'),self.openDir)
		self.connect(self.ui.remoteWidget,SIGNAL('itemDoubleClicked(QTreeWidgetItem *,int)'),self.openRemoteDir)
	
		self.ui.textBrowser.append('<b>Hello,Welcome Use Free Ftp.</b>')
		self.ui.textBrowser.append("<font color=red> Copyright (c) </font>2009-9. <font color=blue>angelipin</font>.")
	
	
		self.localtransferlist = []
		self.remotetransferlist = []	

	def encode(self,s,encoding):
		if isinstance(s,unicode):
			print "unicode!!!!!!"
			return s
		else:
			print "not unicode!!!!"
			return unicode(s,encoding)

	def transfer(self):
		print "transfer--------------------------------"	

		self.ui.textBrowser.append("<font color=green>begin transfer</font>")
		self.ui.textBrowser.append("<font color=blue>------------------------------</font>")
		count = 0
		for f in self.localtransferlist:
			self.ui.textBrowser.append("<font color=red>transfer </font> <font color=blue><b>%s</b></font> <font color=black><b>upload</b></font>" % f.name )
			if f.is_dir():
				self.ftp.mkd(f.name)
			else:
				handler = open(f.path,'rb')
				self.ftp.storbinary('STOR '+f.name.encode('UTF-8'),handler,1024)
				handler.close()
			self.localtransferlist[count].setflag(0)
			count = count + 1
			self.updateTransferQueue()
		del self.localtransferlist
		self.localtransferlist = []
		
		count = 0
		for f in self.remotetransferlist:
			print f
			path = os.path.join(self.currentDir,str(f))
			file_handler = open(path,"wb").write
			self.ftp.retrbinary('RETR %s' % f,file_handler,1024)
			self.ui.textBrowser.append("<font color=red>transfer </font> <font color=blue><b>%s</b></font> <font color=black><b>download</b></font>" % f)
				

	def disconnect(self):
		print "disconnect------------------------------"
		self.isFtpConnected = 0		
		self.ftp.close()
		self.ui.textBrowser.append("<font color=red>disconnect from ftp </font>: <b>%s</b>" % self.ftpServerIp)
		self.ui.remoteWidget.clear()

	def localFileList(self,localPath):
		pathinfo = LocalFileInfo(localPath)
		if pathinfo.is_dir():
			filelist = os.listdir(localPath)
			for f in filelist:
				fileinfo = LocalFileInfo(os.path.join(localPath,f))
				self.localtransferlist.append(fileinfo)
				if fileinfo.is_dir():
					self.localFileList(os.path.join(localPath,f))


	def addLocalFileToQueue(self):
		print "add local file to queue"
		
		file = self.ui.localWidget.currentItem().data(0,0)
		print "+++++++++++++++++++++++++++++++++++++++++++++++++++++"
		print "+                  "+unicode(file)+"                          "
		print "+                                                   +"
		print "+                                                   +"
		print "+++++++++++++++++++++++++++++++++++++++++++++++++++++"
		file = self.ui.localWidget.currentItem().data(0,0).toString()
		filename = self.encode(str(file.toUtf8()),'UTF-8')
		print filename
		path = os.path.join(self.currentDir,str(file))
		self.localtransferlist.append(LocalFileInfo(path))
		self.localFileList(path)
		self.updateTransferQueue()

	def updateTransferQueue(self):
		self.ui.queueWidget.clear()
		for f in self.localtransferlist:
			if f.flag :
				item = QTreeWidgetItem([self.encode(f.path,'UTF-8'),u"上传"])
				self.ui.queueWidget.addTopLevelItem(item)
		for f in self.remotetransferlist:
			item = QTreeWidgetItem([f,u'下载'])
			self.ui.queueWidget.addTopLevelItem(item)
		


	def addRemoteFileToQueue(self):
		print "add remote file to queue"
		
		file = self.ui.remoteWidget.currentItem().data(0,0).toString()
		if self.encode(file.toUtf8(),'UTF-8') == self.encode(u'上层目录','UTF-8'):
			self.ftp.cwd('../')
			self.ftp.nlst()
		else:
			self.remotetransferlist.append(file)
		self.updateTransferQueue()

	def updateRemoteFileList(self):
		item = QTreeWidgetItem([u'上层目录','','',''])
		item.setIcon(0,QIcon(":/ICON/parent_dir.png"))
		self.ui.remoteWidget.addTopLevelItem(item)
		for f in self.remoteFileList:
			item = QTreeWidgetItem([f,' ',' ',' ',' '])
			self.ui.remoteWidget.addTopLevelItem(item)

	def connectToServer(self):
		self.ftp.connect(str(self.ftpServerIp),str(self.ftpServerPort))
		self.isFtpConnected = 1
		self.ftp.login(str(self.ftpUsername),str(self.ftpPassword))
		self.ui.textBrowser.append("<font color=red>connect to ftp server </font>: <b>%s</b> <font color=red>Port</font>: <b>%s</b>" % (self.ftpServerIp,self.ftpServerPort))
		print self.ftp.getwelcome()
		print self.ftp.cwd('./')
		self.remoteFileList = self.ftp.nlst()
		self.ui.textBrowser.append("<font closr=blue>NLST </font>")
		self.updateRemoteFileList()
		

	def quickConnect(self):
		print "quickconnet"
		dialog = quickConnectDlg.QuickConnectDlg(self)
		dialog.username.setText('yepin')
		dialog.serverIp.setText('127.0.0.1')
		dialog.password.setText('welcome')
		dialog.serverPort.setText('21')
		if dialog.exec_():
			print "Open Connect Dialog!!"
			if self.isFtpConnected:
				self.ftp.quit()
			print dialog.username.text()
			print dialog.serverIp.text()
			print dialog.password.text()
			print dialog.serverPort.text()
			
			self.ftpUsername = dialog.username.text()
			self.ftpPassword = dialog.password.text()
			self.ftpServerIp = dialog.serverIp.text()
			self.ftpServerPort = dialog.serverPort.text()
			self.remoteDir = dialog.remotePath.text()
			self.connectToServer()

		return 

	def openParentDir(self):
		print self.currentDir
		dir = self.currentDir.split('/')
		if len(dir) <= 2:
			self.currentDir = '/'
		else:
			parentdir = '/'.join(dir[:-1])
			print parentdir
			self.currentDir = parentdir
		self.updateLocalWidget()

	def openDir(self):
		dir = self.ui.localWidget.currentItem().data(0,0).toString().toUtf8()
		if self.encode(dir,'UTF-8') == self.encode(u'上层目录','UTF-8'):
			print u'上层目录'
			self.openParentDir()
		else:
			fileinfo = LocalFileInfo(os.path.join(self.currentDir,str(dir)))
			if fileinfo.is_dir():
				self.currentDir = os.path.join(self.currentDir,str(dir))
				print self.currentDir
				self.updateLocalWidget()
				print "open dir"
			else:
				self.addLocalFileToQueue()
				print "add file to transfer"

	def openRemoteDir(self):
		dir = self.ui.remoteWidget.currentItem().data(0,0).toString()
		if self.encode(dir.toUtf8(),'UTF-8') == self.encode(u'上层目录','UTF-8'):
			self.ftp.cwd('../')
			remotedir = self.remoteCurrentDir.split('/')
			self.remoteCurrentDir = '/'.join(remotedir[:-1])
			self.ui.textBrowser.append("Dir : <font color=red>%s</font>" % self.remoteCurrentDir)	
		else:
			self.remoteCurrentDir = os.path.join(self.remoteCurrentDir,str(dir))
			self.ui.textBrowser.append("Dir : <font color=red>%s</font>"%self.remoteCurrentDir)
			print self.remoteCurrentDir
			self.ftp.cwd(str(dir))
		self.updateRemoteWidget()

	def updateRemoteWidget(self):
		del self.remotefilelist
		self.remotefilelist = []
		self.remotefilelist = self.ftp.nlst()
		self.ui.remoteWidget.clear()
		item= QTreeWidgetItem([u'上层目录','','',''])
		item.setIcon(0,QIcon(":/ICON/parent_dir.png"))
		self.ui.remoteWidget.addTopLevelItem(item)
		for f in self.remotefilelist:
			item = QTreeWidgetItem([f,' ',' ',' '])
			self.ui.remoteWidget.addTopLevelItem(item)

		

	def updateLocalFileList(self,dir):
		file = LocalFileInfo(dir)
		if file.is_dir():
			del self.fileList
			self.fileList = []
			filelist = os.listdir(dir)
			for f in filelist:
				fileinfo = LocalFileInfo(os.path.join(self.currentDir,f))
				self.fileList.append(fileinfo)

	def updateLocalWidget(self):
		self.ui.localWidget.clear()
		item = QTreeWidgetItem([u'上层目录','','',''])
		item.setIcon(0,QIcon(":/ICON/parent_dir.png"))
		self.ui.localWidget.addTopLevelItem(item)
		self.updateLocalFileList(self.currentDir)
		for f in self.fileList:
			item = QTreeWidgetItem([self.encode(f.name,'UTF-8'),str(f.size),time.ctime(f.mtime),' '])
			if f.type == 'Dir':
				item.setIcon(0,QIcon(":/ICON/folder.png"))
			self.ui.localWidget.addTopLevelItem(item)

	def createAction(self,text,slot=None,shortcut=None,icon=None,tip=None,checkable=False,signal="triggered()"):
		action = QAction(text,self)
		if icon is not None:
			action.setIcon(QIcon(":/ICON/%s.png" % icon))
		if shortcut is not None:
			action.setShortcut(shortcut)
		if tip is not None:
			action.setToolTip(tip)
			action.setStatusTip(tip)
		if slot is not None:
			self.connect(action,SIGNAL(signal),slot)
		if checkable:
			action.setCheckable(True)
		return action

	def addActions(self,target,actions):
		for action in actions:
			if action is None:
				taget.addSeparator()
			else:
				target.addAction(action)

def main():
	app = QApplication(sys.argv)
	window = FreeFtpView()
	window.show()
	sys.exit(app.exec_())

if __name__ == "__main__":
	main()
